package top.glkj.hms.security;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import top.glkj.hms.config.JwtConfig;
import top.glkj.hms.entity.User;
import top.glkj.hms.service.UserService;
import top.glkj.hms.utils.RedisUtils;
import top.glkj.hms.utils.SpringUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author : xgl
 * @version : 0.0.1
 * @date :2020/11/28 1:54
 */
@Slf4j
public class JwtAuthenticationTokenFilter extends BasicAuthenticationFilter {

    private final UserService userService = (UserService) SpringUtils.getBean("userServiceImpl");
    private final RedisUtils redisUtils = (RedisUtils) SpringUtils.getBean(RedisUtils.class);
    public JwtAuthenticationTokenFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Cacheable(value = "jwt")
    @Override
    public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {

        // 获取请求头中JWT的Token
        String tokenHeader = request.getHeader(JwtConfig.tokenHeader);
        //if (tokenHeader.startsWith(StaticValue.BACKSLASH)&&tokenHeader.endsWith(StaticValue.BACKSLASH)){
        //    tokenHeader=tokenHeader.substring(1,tokenHeader.length()-1);
        //};
        if (StringUtils.isEmpty(tokenHeader)) {
            Cookie[] cookies = request.getCookies();
            for (Cookie c : cookies) {
                if (c.getName().equals(JwtConfig.tokenHeader)) {
                    tokenHeader = c.getValue();
                }
            }
        }
        if (null != tokenHeader && tokenHeader.startsWith(JwtConfig.tokenPrefix)) {
            try {
                // 截取JWT前缀
                String token = tokenHeader.replace(JwtConfig.tokenPrefix, "");
                // 解析JWT
                Claims claims = Jwts.parser()
                        .setSigningKey(JwtConfig.secret)
                        .parseClaimsJws(token)
                        .getBody();
                // 获取用户名
                String username = claims.getSubject();
                String userId = claims.getId();
                if (!StringUtils.isEmpty(username) && !StringUtils.isEmpty(userId)) {
                    // 获取角色
                    //组装参数
                    User user = (User) userService.loadUserByUsername(username);
                    UsernamePasswordAuthenticationToken
                            authentication = new UsernamePasswordAuthenticationToken(user, userId, user.getAuthorities());
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            } catch (ExpiredJwtException e) {
                log.error(e + "Token过期");
            } catch (Exception e) {
                e.printStackTrace();
                log.error("Token无效");
            }
        }
        filterChain.doFilter(request, response);
    }
}
